package com.avicit.zipkinkafkaesserver.dao.es;

import com.avicit.zipkinkafkaesserver.entity.ZipkinInterfaceDuration;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryRewriteContext;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.sort.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.stereotype.Repository;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Repository
public class ZipkinInterfaceDurationEsDao  extends BaseEsDao<ZipkinInterfaceDuration>{
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Override
    ElasticsearchTemplate elasticsearchTemplate() {
        return elasticsearchTemplate;
    }

    /**
     * 条件查询
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param min 最小耗时
     * @param max 最大耗时
     * @param topN topN
     * @return
     */
    public List<ZipkinInterfaceDuration> query(long startTime, long endTime, long min, long max, int topN, String index, String type) {
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("createTime");
        rangeQueryBuilder.from(startTime).to(endTime==0?System.currentTimeMillis():endTime)
                .includeLower(true)//允许取边界值
                .includeUpper(true);

        SearchRequestBuilder searchRequestBuilder = elasticsearchTemplate.getClient().prepareSearch(index)
                .setTypes(type)
                .setQuery(rangeQueryBuilder);//时间过滤
        RangeQueryBuilder interfaceDuration = QueryBuilders.rangeQuery("interfaceDuration");
        //设置最大值，最小值
        if (max ==0 && min >0) {
            interfaceDuration.from(min).includeLower(true);
        }
        if (max>0 && min == 0) {
            interfaceDuration.to(max).includeUpper(true);
        }
        if (max>0 && min > 0) {
            interfaceDuration.from(min).to(max).includeUpper(true).includeUpper(true);
        }

        searchRequestBuilder = searchRequestBuilder.setQuery(interfaceDuration);

        //耗时倒排
        if (topN>0) {
            FieldSortBuilder sortBuilder = SortBuilders.fieldSort("interfaceDuration").order(SortOrder.DESC);
            searchRequestBuilder = searchRequestBuilder.addSort(sortBuilder).setSize(topN);
        }
        SearchResponse response = searchRequestBuilder.execute().actionGet();

        List<ZipkinInterfaceDuration> zipkinInterfaceDurations = new ArrayList<>();
        response.getHits().forEach(item->{
            Map<String, Object> sourceAsMap = item.getSourceAsMap();
            zipkinInterfaceDurations.add(ZipkinInterfaceDuration.builder()
//                    .id(item.getId())
                    .interfaceMethod((String) sourceAsMap.get("interfaceMethod"))
                    .queryKey((String) sourceAsMap.get("queryKey"))
                    .interfaceIp((String) sourceAsMap.get("interfaceIp"))
                    .interfacePath((String)sourceAsMap.get("interfacePath"))
                    .interfaceDuration((Double)sourceAsMap.get("interfaceDuration"))
                    .serverName((String) sourceAsMap.get("serverName"))
                    .build());
        });
        return zipkinInterfaceDurations;
    }

    public List<ZipkinInterfaceDuration> pecentQuery(long startTime, long endTime, long min, long max, int topN, String index, String type) {
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("createTime");
        rangeQueryBuilder.from(startTime).to(endTime)
                .includeLower(true)//允许取边界值
                .includeUpper(true);

        SearchRequestBuilder searchRequestBuilder = elasticsearchTemplate.getClient().prepareSearch(index)
                .setTypes(type)
                .setQuery(rangeQueryBuilder);//时间过滤

//        searchRequestBuilder.addAggregation(AggregationBuilders.percentiles("percent").field("interfaceDuration"));

//        searchRequestBuilder.addAggregation(AggregationBuilders.percentileRanks("percent",new double[]{64297,7429700}).field("interfaceDuration"));
//        SearchResponse response = searchRequestBuilder.execute().actionGet();
//        Aggregations aggregations = response.getAggregations();
        return null;
    }
}
